package top.v5it.japi.ddd.example.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.extra.spring.SpringUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.v5it.japi.ddd.core.repository.Repository;
import top.v5it.japi.ddd.core.service.impl.BasicServiceImpl;
import top.v5it.japi.ddd.example.domain.event.ProductReviewDTO;
import top.v5it.japi.ddd.example.domain.proxy.ProductVO;
import top.v5it.japi.ddd.example.product.entity.Product;
import top.v5it.japi.ddd.example.product.entity.ProductReview;
import top.v5it.japi.ddd.example.product.event.ProductReviewEvent;
import top.v5it.japi.ddd.example.product.service.ProductService;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhanpu
 * @date 2023/11/9
 */
@Service(ProductService.SERVICE_NAME)
@RequiredArgsConstructor
public class ProductServiceImpl extends BasicServiceImpl<Repository> implements ProductService {

    private final RestTemplate restTemplate;
    private final Snowflake snowflake;

    @Override
    public void add(Product entity) {
        Assert.notNull(entity, "请求参数[entity]不能为空");
        Optional.of(entity).filter(t -> Objects.isNull(t.getId())).ifPresent(t -> t.setId(snowflake.nextId()));
        basicDao.insert(entity);
    }

    @Override
    public void modify(Product entity) {
        Assert.notNull(entity, "请求参数[entity]不能为空");
        basicDao.update(entity);
    }

    @Override
    public Product searchById(Long id) {
        Assert.notNull(id, "请求id不能为空");
        return basicDao.load(id, new Product());
    }

    @Override
    public List<Product> searchByIds(List<Long> ids) {
        Assert.notNull(ids, "请求ids不能为空");
        return basicDao.loadForList(ids, new Product());
    }

    @Override
    public void addProductReview(ProductReview entity) {
        Assert.notNull(entity, "请求参数[entity]不能为空");
        final Product product = this.searchById(entity.getProduct_id());
        Assert.notNull(product, "请求参数[productReview.product_id = {}]非法", entity.getProduct_id());
        final Object result = restTemplate.getForObject("http://example-member/orm/member/search_by_id?id=" + entity.getMember_id(), Object.class);
        Assert.notNull(result, "请求参数[productReview.member_id = {}]非法", entity.getMember_id());
        Optional.of(entity).filter(t -> Objects.isNull(t.getId())).ifPresent(t -> t.setId(snowflake.nextId()));
        Optional.of(entity).filter(t -> Objects.isNull(t.getReview_date())).ifPresent(t -> t.setReview_date(LocalDateTime.now(ZoneId.systemDefault())));
        basicDao.insert(entity);

        // 发布事件
        final ProductReviewDTO productReviewDTO = new ProductReviewDTO();
        productReviewDTO.setMember_id(entity.getMember_id());
        final ProductReviewEvent event = new ProductReviewEvent(productReviewDTO);
        SpringUtil.publishEvent(event);

    }

    @Override
    public ProductVO getProduct(Long id) {
        final Product product = this.searchById(id);
        return BeanUtil.copyProperties(product, ProductVO.class);
    }

    @Override
    public List<ProductVO> getProducts(List<Long> ids) {
        final List<Product> products = this.searchByIds(ids);
        return products.stream().map(t -> BeanUtil.copyProperties(t, ProductVO.class)).collect(Collectors.toList());
    }
}
